import json
import re

import pandas as pd

from Agent.Agent import Agent
from llm import llm, super_eval, enc

prompt = '''

以下是深海作业A下放阶段各动作的判断规则详细解释：

### 1.ON DP（动力定位开启）
- **相关字段**：P3_33、P3_18
- **判断规则**：当P3_33或P3_18的数值从0开始增加时，即表示动力定位系统开启。
- **解释**：动力定位系统是船舶在海中保持位置和航向的重要系统。在进行深海作业时，开启动力定位是确保作业安全和准确的前提条件。因此，在下放阶段开始前，需要先开启动力定位系统，以保证后续作业的顺利进行。

### 2.A架开机
- **相关字段**：Ajia-3_v、Ajia-5_v
- **判断规则**：当Ajia-3_v和Ajia-5_v的电流值从“error”变为0时，表示A架开机。
- **解释**：A架是深海作业中用于发射和回收设备的重要起重装置。在作业开始前，需要先启动A架，使其处于工作状态，以便后续进行设备的下放操作。

### 3.折臂吊车开机
- **相关字段**：13-11-6_v
- **判断规则**：当13-11-6_v的数值从0开始增加时，表示折臂吊车开机。
- **解释**：折臂吊车是一种灵活的起重设备，主要用于小艇等设备的下放和回收。在下放阶段，需要启动折臂吊车，为小艇的下放做好准备。

### 4.小艇检查完毕
- **相关字段**：13-11-6_v
- **判断规则**：当13-11-6_v的数值增加到某个值后回落，回落前的最后一个值对应的时刻即为小艇检查完毕的时间。
- **解释**：在小艇下水之前，需要对其进行详细检查，确保其状态良好，符合下水作业的要求。检查完毕后，相关数值会有所体现。

### 5.小艇入水
- **相关字段**：13-11-6_v
- **判断规则**：当13-11-6_v的数值增加到某个值后回落，回落前的最后一个值对应的时刻即为小艇入水的时间。
- **解释**：小艇入水是下放阶段的重要环节，标志着小艇正式开始参与作业。通过监测相关数值的变化，可以准确判断小艇入水的时刻。

### 6.征服者起吊
- **相关字段**：Ajia-3_v、Ajia-5_v
- **判断规则**：当Ajia-3_v和Ajia-5_v的电流值从稳定值（50多）开始增加时，表示征服者起吊。
- **解释**：征服者是深海作业中的重要设备，起吊操作是将其从船上吊起，准备进行水下作业的关键步骤。电流值的变化反映了设备的运行状态，从而可以判断起吊的开始时刻。

### 7.征服者入水
- **相关字段**：Ajia-3_v、Ajia-5_v
- **判断规则**：在缆绳解除的时间点往前推一分钟，即为征服者入水的时间。
- **解释**：征服者入水后，需要进行一系列的水下作业。通过在缆绳解除前一分钟确定入水时间，可以更准确地把握作业流程。

### 8.缆绳解除
- **相关字段**：Ajia-3_v、Ajia-5_v
- **判断规则**：当Ajia-3_v和Ajia-5_v的电流值从高值回落至稳定值（50多）时，表示缆绳解除。
- **解释**：缆绳解除意味着征服者已经完全入水并开始独立作业，不再需要船上的设备进行牵引。电流值的回落反映了这一状态的变化。

### 9.A架摆回
- **相关字段**：Ajia-3_v、Ajia-5_v
- **判断规则**：在征服者入水后，当Ajia-3_v和Ajia-5_v的电流值重新增加到峰值时，表示A架摆回。
- **解释**：A架摆回是将A架从工作位置恢复到初始位置的操作，为后续的回收阶段做好准备。电流值的重新增加反映了A架的再次动作。

### 10.小艇落座
- **相关字段**：13-11-6_v
- **判断规则**：当13-11-6_v的数值增加到某个值后回落，回落前的最后一个值对应的时刻即为小艇落座的时间。
- **解释**：小艇落座表示小艇已经完成下放任务，稳定地放置在预定位置，准备进行后续作业。

### 11.折臂吊车关机
- **相关字段**：13-11-6_v
- **判断规则**：当13-11-6_v的数值归零时，表示折臂吊车关机。
- **解释**：在下放阶段结束后，折臂吊车完成任务，可以关闭以节省能源并避免不必要的损耗。

### 12.A架关机
- **相关字段**：Ajia-3_v、Ajia-5_v
- **判断规则**：当Ajia-3_v和Ajia-5_v的电流值变为“error”时，表示A架关机。
- **解释**：A架在完成下放阶段的所有任务后，可以关闭以待下次使用。

### 13.OFF DP（动力定位关闭）
- **相关字段**：P3_33、P3_18
- **判断规则**：当P3_33和P3_18的数值归零时，表示动力定位系统关闭。
- **解释**：在下放阶段结束后，如果船舶不需要继续进行其他作业，可以关闭动力定位系统，以节省能源并减少设备磨损。

以下是深海作业A回收阶段各动作的判断规则详细解释：

### 1.A架开机
- **相关字段**：Ajia-3_v、Ajia-5_v
- **判断规则**：当Ajia-3_v和Ajia-5_v的电流值从“error”变为0时，表示A架开机。
- **解释**：在回收阶段开始前，需要先启动A架，使其处于工作状态，以便后续进行设备的回收操作。

### 2.折臂吊车开机
- **相关字段**：13-11-6_v
- **判断规则**：当13-11-6_v的数值从0开始增加时，表示折臂吊车开机。
- **解释**：折臂吊车在回收阶段主要用于小艇等设备的回收，需要先启动设备。

### 3.A架摆出
- **相关字段**：Ajia-3_v、Ajia-5_v
- **判断规则**：在征服者起吊前，当Ajia-3_v和Ajia-5_v的电流值到达峰值时，表示A架摆出。
- **解释**：A架摆出是将A架从初始位置移动到工作位置，为起吊征服者做好准备。

### 4.小艇检查完毕
- **相关字段**：13-11-6_v
- **判断规则**：当13-11-6_v的数值增加到某个值后回落，回落前的最后一个值对应的时刻即为小艇检查完毕的时间。
- **解释**：在小艇回收前，需要对其进行检查，确保其状态良好，符合回收条件。

### 5.小艇入水
- **相关字段**：13-11-6_v
- **判断规则**：当13-11-6_v的数值增加到某个值后回落，回落前的最后一个值对应的时刻即为小艇入水的时间。
- **解释**：小艇入水是回收阶段的开始，表示小艇已经进入水中，准备进行回收操作。

### 6.缆绳挂妥
- **相关字段**：Ajia-3_v、Ajia-5_v
- **判断规则**：在征服者出水前一分钟，当Ajia-3_v和Ajia-5_v的电流值开始增加时，表示缆绳挂妥。
- **解释**：缆绳挂妥意味着征服者的缆绳已经固定好，准备将其从水中吊起。

### 7.征服者出水
- **相关字段**：Ajia-3_v、Ajia-5_v
- **判断规则**：当Ajia-3_v和Ajia-5_v的电流值达到峰值时，表示征服者出水。
- **解释**：征服者出水是回收阶段的关键步骤，表示征服者已经从水中被吊起，即将被放置在船上。

### 8.小艇落座
- **相关字段**：13-11-6_v
- **判断规则**：当13-11-6_v的数值增加到某个值后回落，回落前的最后一个值对应的时刻即为小艇落座的时间。
- **解释**：小艇落座表示小艇已经完成回收，稳定地放置在预定位置。

### 9.折臂吊车关机
- **相关字段**：13-11-6_v
- **判断规则**：当13-11-6_v的数值归零时，表示折臂吊车关机。
- **解释**：在回收阶段结束后，折臂吊车完成任务，可以关闭以节省能源。

### 10.征服者落座
- **相关字段**：Ajia-3_v、Ajia-5_v
- **判断规则**：当Ajia-3_v和Ajia-5_v的电流值从高值回落至稳定值（50多）时，表示征服者落座。
- **解释**：征服者落座表示征服者已经完全放置在船上，回收操作完成。

### 11.A架关机
- **相关字段**：Ajia-3_v、Ajia-5_v
- **判断规则**：当Ajia-3_v和Ajia-5_v的电流值变为“error”时，表示A架关机。
- **解释**：在回收阶段结束后，A架完成所有任务，可以关闭以待下次使用。

以上动作除了开机先后外，基本按照上述顺序运行。

我会给你问题和表格，基于表格回答问题。
'''

time_prompt = '''
请提取以下问题中的时间范围，如果明确时分，则开始时间提前十五分钟，结束时间延时15分钟，只有日期无需提前和延时,只有一个之间点则前后反馈扩展到1h

按照
```json
[
{"start_time":"yyyy-mm-dd hh:mm:ss","end_time":"yyyy-mm-dd hh:mm:ss"},
...
]
```
的格式输出。
示例:
user:2024/8/24 8:45 ~ 8:55之间，发生了哪些关键动作,9月10号呢？
assistant:```json
[
  {"start_time":"2024-08-24 08:30:00","end_time":"2024-08-24 09:10:00"},
  {"start_time":"2024-09-10 00:00:00","end_time":"2024-09-11 00:00:00"}
]
```
user:2024/8/24 8:45，发生了什么动作？
assistant:```json
[
  {"start_time":"2024-08-24 07:45:00","end_time":"2024-08-24 09:45:00"}
]
```
'''


class DeepSeaAgent(Agent):

    def __init__(self, name,
                 description,
                 system_prompt,
                 agent_type,
                 llm_engine,
                 agents=None,
                 rag=None, sample=None):
        super().__init__(name,
                         description,
                         system_prompt,
                         agent_type,
                         llm_engine,
                         agents,
                         rag)

        self.sample = sample

    def get_data(self, start_time, end_time):
        df = pd.read_excel('mark5.xlsx')

        # 将 csvTime 列转换为日期时间格式
        df['csvTime'] = pd.to_datetime(df['csvTime'])

        # 将输入的 start_time 和 end_time 转换为日期时间格式
        start_time = pd.to_datetime(start_time)
        end_time = pd.to_datetime(end_time)

        # 按照时间过滤数据
        filtered_df = df[(df['csvTime'] >= start_time) & (df['csvTime'] <= end_time)]

        return filtered_df

    def del_row(self, content: str):
        content_list = content.split('\n')
        content_list = [i for i in content_list if not re.search('\| +\|', i)]
        if len(content_list) > 50:
            content_list = content_list[:20] + content_list[-20:]
        return '\n'.join(content_list)

    def build_prompt(self, question):
        self.messages = [{"role": "system", "content": self.system_prompt},
                         ]


    def run(self, question):
        time_range = self.llm_engine([{"role": "system", "content": time_prompt},
                                      {"role": "user", "content": question + '\n请输出时间范围json:'}])
        time_range = super_eval(time_range)

        self.build_prompt(question)

        combined_df = pd.DataFrame()  # 初始化一个空的 DataFrame

        for i in time_range:
            sub_df = self.get_data(i["start_time"], i["end_time"])
            combined_df = pd.concat([combined_df, sub_df], ignore_index=True)

        combined_df = combined_df[['actionType', 'deviceName', 'actionName', 'csvTimeMinute']]
        combined_df = combined_df.drop_duplicates()
        self.messages.append({"role": "user",
                              "content": f'''
当前问题：{question}
数据如下：
---
{combined_df.to_markdown(index=False)}
---
请基于日志思考分析题目,只回答日志可以覆盖到的答案，重新思考。
'''})

        sea_log = self.llm_engine(self.messages)

        with open('./sample/deepsea3.jsonl', 'a', encoding='utf-8') as fw:
            fw.write(
                json.dumps({"question": question, "messages": self.messages[1:]}, ensure_ascii=False)
            )
            fw.write('\n')

        return re.sub('<think>.*?</think>', '', sea_log, re.DOTALL)


from get_sample import get_deepsea_sample

DeepSeaAgentConfig = {"name": 'xxx',
                      "description": 'xxx',
                      'system_prompt': prompt,
                      'agent_type': 'plan-action',
                      'llm_engine': llm,
                      'sample': None,
                      'agents': None}

deep_sea_agent = DeepSeaAgent(**DeepSeaAgentConfig)
